package com.hk.context;

import com.hk.Mgr.web.message.kyc.KycRes;
import com.hk.Mgr.web.message.kyc.QuestionPhoneRes;
import com.hk.app.utils.YingmiOpenAPI;
import com.hk.commons.HqlFilter;
import com.hk.commons.ReqToModelHelper;
import com.hk.commons.enm.KYCEnum;
import com.hk.commons.entity.Answer;
import com.hk.commons.entity.Question;
import com.hk.commons.entity.sys.SysUser;
import com.hk.commons.vo.yingmi.TerminalRequestDTO;
import com.hk.service.kyc.IQuestion;
import com.hk.service.sys.IAnswer;
import com.hk.service.sys.ISysUser;
import com.hk.yingmi.YingmiOpenAPIConstant;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Antinomy on 17/9/28.
 */
@Service
public class RiskEvaluationContext {

    private Logger logger = LoggerFactory.getLogger(RiskEvaluationContext.class);

    public static final int KYC_QUESTION_LENGTH = 10;

    @Autowired
    private IQuestion questionService;

    @Autowired
    private IAnswer answerService;

    @Autowired
    private ISysUser sysUserService;

    @Autowired
    private YingmiOpenAPI openAPI;

    private ExecutorService executor = Executors.newFixedThreadPool(1);


    public List<QuestionPhoneRes> listQuestions(Long groupId) {
        List<QuestionPhoneRes> questionPhoneReslist = new ArrayList<>();

        HqlFilter hqlFilter = new HqlFilter();

        if (groupId == null)
            groupId = 1L;

        hqlFilter.addEQFilter("groupId", groupId);
        hqlFilter.addSort("seqNum");
        hqlFilter.addOrder("asc");

        List<Question> list = questionService.findByFilter(hqlFilter);

        for (Question question : list) {

            QuestionPhoneRes quPhoneRes = new QuestionPhoneRes();
            // 设置题目
            quPhoneRes.setQuestion(question.getQuestion());
            // 设置答案
            String[] selectionArray = null;
            String selectionStr = question.getAnswer();
            selectionArray = selectionStr.split(",");
            quPhoneRes.setSelection(selectionArray);
            // 设置顺序
            quPhoneRes.setSeqNum(question.getSeqNum().toString());

            questionPhoneReslist.add(quPhoneRes);
        }
        return questionPhoneReslist;
    }

    public KycRes calcRiskLevel(String[] selectionArr, Long groupId) {
        KycRes kycRes = new KycRes();

        // 01获取答题的得分
        Integer score = calcScore(selectionArr, groupId,kycRes);
        logger.info("app/kcyCtrl/answerAll calc Score : " + score);

        // 02 获取kyc的评级
        if(groupId != null && groupId.equals(2L))
        {
            kycRes = calcGroup2RiskLevel(kycRes,score);
        }
        else {
            kycRes = calcGroup1RiskLevel(kycRes,score);
        }

        logger.info("app/kcyCtrl/answerAll result : " + kycRes.toString());

        kycRes.setGroupId(groupId);

        return kycRes;
    }

    public boolean storeRiskLevelResult(Long userId, String selection, KycRes calcResult, TerminalRequestDTO terminalReq) {
        Answer an = new Answer();

        an.setMobileId(terminalReq.getMobileId());
        an.setCts(System.currentTimeMillis());
        an.setAnswerArray(selection);
        an.setUserId(userId);

        an.setScore(calcResult.getRiskLevel());
        an.setScoreDesc(calcResult.getDesc());
        an.setScoreLongDesc(calcResult.getLongDesc());
        an.setTotalScore(calcResult.getTotalScore());
        an.setGroupId(calcResult.getGroupId());

        an.setTerminalIP(terminalReq.getTerminalIP());
        an.setTerminalType(terminalReq.getTerminalType());
        an.setTerminalInfo(terminalReq.getTerminalInfo());
        an.setReferenceNo(terminalReq.getReferenceNo());

        return syncKYC(an,terminalReq);
    }

    public Boolean syncRiskLevelToYingmi(Long userId,TerminalRequestDTO terminalReq){
        SysUser user = sysUserService.findById(userId);
        if (user == null) {
            return false;
        }

        // 保存用户信息到数据库中
        Answer existAnswer = answerService.getByUserId(userId);

        if (existAnswer == null
                || !existAnswer.getGroupId().equals(2L)) {
            return false;
        }

        sendRiskEvaluationToYingmi(existAnswer,user,terminalReq);

        return true;
    }

    /**
     * 获取用户的风险测评信息, 并且保存
     *
     * @param
     * @param
     * @return KycRes 封装后的Kyc
     */
    private KycRes calcGroup1RiskLevel(KycRes resp,Integer riskScore) {
        logger.info("calc Group1 Risk Level function riskScore = " + riskScore);


        if (riskScore <= 10) {
            updateKyc(resp, KYCEnum.KYCRiskLevel_A1, riskScore);
        }

        if (11 <= riskScore && riskScore <= 19) {
            updateKyc(resp, KYCEnum.KYCRiskLevel_A2, riskScore);
        }

        if (20 <= riskScore && riskScore <= 29) {
            updateKyc(resp, KYCEnum.KYCRiskLevel_A3, riskScore);
        }

        if (30 <= riskScore && riskScore <= 39) {
            updateKyc(resp, KYCEnum.KYCRiskLevel_A4, riskScore);
        }

        if (40 <= riskScore && riskScore <= 50) {
            updateKyc(resp, KYCEnum.KYCRiskLevel_A5, riskScore);
        }

        logger.info("score = " + riskScore
                + "  scoreType = " + resp.getRiskLevel()
                + "   Kyc Desc = " + resp.getDesc() + "  : " + resp.getLongDesc());

        return resp;
    }

    private KycRes calcGroup2RiskLevel(KycRes resp,Integer riskScore) {
        logger.info("calc Group2 Risk Level function riskScore = " + riskScore);

        if (riskScore <= 12) {
            if (resp.getHasZeroRecord())
                updateKyc(resp, KYCEnum.KYC_RISK_LEVEL_C1_1, riskScore);
            else
                updateKyc(resp, KYCEnum.KYC_RISK_LEVEL_C1, riskScore);
        }

        if (13 <= riskScore && riskScore <= 20) {
            updateKyc(resp, KYCEnum.KYC_RISK_LEVEL_C2, riskScore);
        }

        if (21 <= riskScore && riskScore <= 28) {
            updateKyc(resp, KYCEnum.KYC_RISK_LEVEL_C3, riskScore);
        }

        if (29 <= riskScore && riskScore <= 36) {
            updateKyc(resp, KYCEnum.KYC_RISK_LEVEL_C4, riskScore);
        }

        if (37 <= riskScore && riskScore <= 43) {
            updateKyc(resp, KYCEnum.KYC_RISK_LEVEL_C5, riskScore);
        }

        logger.info("score = " + riskScore
                + "  scoreType = " + resp.getRiskLevel()
                + "   Kyc Desc = " + resp.getDesc() + "  : " + resp.getLongDesc());

        return resp;
    }

    private void updateKyc(KycRes resp, KYCEnum kycEnum, Integer totalScore) {
        resp.setTotalScore(Long.valueOf(totalScore));
        resp.setRiskLevel(kycEnum.getCode());
        resp.setDesc(kycEnum.getDesc());
        resp.setLongDesc(kycEnum.getLongDesc());
    }

    /**
     * 获取用户的风险测评的结果
     *
     * @param selectArr
     */
    private Integer calcScore(String[] selectArr, Long groupId, KycRes kycRes) {

        Integer riskScore = 0;

        for (int i = 0; i < KYC_QUESTION_LENGTH; i++) {
            int seqNum = i + 1;
            Integer questionValue = getQuestionValue(selectArr[i], seqNum, groupId);

            if (questionValue.equals(0)) {
                kycRes.setHasZeroRecord(true);
            }

            riskScore += questionValue;
        }

        return riskScore;
    }

    /*
    * 获取每一个题的得分
    */
    private Integer getQuestionValue(String selection, Integer seqNum, Long groupId) {
        logger.info("question seqNum = " + seqNum + " selection = " + selection);
        Integer result = 0;

        Long aLongSeqNum = Long.valueOf(seqNum);
        Question question = questionService.findBySeqNumAndGroupId(aLongSeqNum, groupId);

        if (question != null) {

            // 获取分值
            String valueStr = question.getValue();
            String[] valueArray = valueStr.split(",");

            // 用户选择项
            Integer selectQuestionNum = Integer.valueOf(selection);
            logger.info("select Question Num = " + selectQuestionNum + "   valArray.length = " + valueArray.length);

            if (selectQuestionNum < valueArray.length + 1) {
                result = Integer.valueOf(valueArray[selectQuestionNum - 1]);
            }
        }

        logger.info("return question value = {}", result);

        return result;
    }

    /**
     * 更新用户信息
     */
    private boolean syncKYC(Answer an,TerminalRequestDTO terminalReq) {
        Long userId = an.getUserId();

        SysUser user = sysUserService.findById(userId);
        if (user == null) {
            return false;
        }

        logger.info("userId =  " + userId);

        // 保存用户信息到数据库中
        Answer existAnswer = answerService.getByUserId(userId);

        if (existAnswer == null) {
            answerService.add(an);
        } else {
            // 如果存在旧的数据，则直接修改
            Long oldAnId = existAnswer.getId();
            ReqToModelHelper.copyReqValueToModel(an, existAnswer);
            existAnswer.setId(oldAnId);

            answerService.update(existAnswer);
        }

        //同步测评结果到盈米
        sendRiskEvaluationToYingmi(an, user,terminalReq);

        //更新合同url
        answerService.updKycUrl(userId);

        return true;
    }

    private void sendRiskEvaluationToYingmi(Answer an, SysUser user,TerminalRequestDTO terminalReq) {
        if (StringUtils.isBlank(user.getAccountId())){
            return;
        }

        try {

            Runnable task = () -> {
                Map<String, String> params = new HashMap<>();
                params.put("brokerUserId", user.getName());
                params.put("accountId", user.getAccountId());
                params.put("selections", an.getAnswerArray());

                openAPI.applyTerminalInfo(params,terminalReq);
                params.put("referenceNo", terminalReq.getReferenceNo());

                String result = openAPI.sslPost(YingmiOpenAPIConstant.ACCOUNT_ANSWER_SURVEY_LV5, params);
                logger.info("Sync result to Yingmi /account/answerRiskSurvey  : ", result);
            };

            executor.execute(task);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
